﻿//=====================================================================================================
// LocalizationLibrary
// The Localization Library is a collection of reusable software components that provide 
// support for localization. This library enables you to localize WPF, Silverlight and WP7 applications.
// (http://localizationlibrary.codeplex.com)
//=====================================================================================================
// Author: Nicola Gallo (Website: www.nicola.gallo.name, Email: nicolagmt@hotmail.it) 
//=====================================================================================================

namespace ReflectionStudio.LocalizationLibrary.Attributes
{
    //.NET References
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using ReflectionStudio.Core.Interface;
    /// <summary>
    /// Indicates that the target property should be localized using a dynamic resource.
    /// This attribute should be used on property where the own class implements <see cref="System.ComponentModel.INotifyPropertyChanged"/>
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
    public class LocalizeDynamicallyAttribute : Attribute, ILocalizationAttribute
    {
        //Fields

        private String _language;
        private String _tmpResourceID = Guid.NewGuid().ToString();

        //Constructors

        /// <summary>
        /// Creates a new instance of the <see cref="LocalizeDynamicallyAttribute"/> class (default constructor).
        /// </summary>
        public LocalizeDynamicallyAttribute() : this(null) { }

        /// <summary>
        /// Creates a new instance of the <see cref="LocalizeDynamicallyAttribute"/> class. 
        /// </summary>
        /// <param name="resourceID">Specifies the identifier of the resource.</param>
        public LocalizeDynamicallyAttribute(String resourceID) : this(resourceID, null, null) { }

        /// <summary>
        /// Creates a new instance of the <see cref="LocalizeDynamicallyAttribute"/> class.
        /// </summary>
        /// <param name="resourceID">Specifies the identifier of the resource.</param>
        /// <param name="language">Specifies the language.</param>
        /// <param name="value">Specifies the object.</param>
        public LocalizeDynamicallyAttribute(String resourceID, String language, Object value)
        {
            this.ResourceID = resourceID;
            this.Language = language;
            this.Value = value;
        }

        //Properties

        /// <summary>
        /// Gets resource's identifier.
        /// </summary>
        public String ResourceID { get; private set; }

        /// <summary>
        /// Gets/Sets resource's language. Accepts null value.
        /// </summary>
        /// <exception cref="ArgumentException">
        /// Thrown whether the input value is an invalid language.
        /// </exception>
        public String Language 
        {
            get 
            {
                return this._language;
            }
            set 
            {
                if ((value != null) && (!LocalizationLibrary.Language.Validate(value)))
                {
                    throw new ArgumentException("Invalid language.");
                }
                this._language = value;
            }
        }

        /// <summary>
        /// Gets/Sets resource's value.
        /// </summary>
        public Object Value { get; set; }

        /// <summary>
        /// Gets/Sets the policy should accomplish the engine in case of version conflicting.
        /// </summary>
        public VersionConflictPolicy Policy { get; set; }

        //Methods

        /// <summary>
        /// Serves as a hash function for <see cref="LocalizeDynamicallyAttribute"/> type.
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return (this.ResourceID == null) ? this._tmpResourceID.GetHashCode() : this.ResourceID.GetHashCode();
        }

        /// <summary>
        /// Determines whether the specified <see cref="LocalizeDynamicallyAttribute"/> is equals to the current <see cref="LocalizeDynamicallyAttribute"/>.
        /// </summary>
        /// <param name="obj">Instance.</param>
        /// <returns>True whether the input instance is equals to the current instance otherwise false.</returns>
        public override bool Equals(object obj)
        {
            if (this == obj)
            {
                return true;
            }
            else if ((obj == null) || (obj.GetType() != this.GetType()))
            {
                return false;
            }
            LocalizeDynamicallyAttribute instance = obj as LocalizeDynamicallyAttribute;
            return instance.ResourceID.Equals(this.ResourceID);
        }
    }
}